#include "shape.h"
#include "shapeparameter.h"

Shape::Shape(QObject* parent) :QObject(parent)
, m_borderWidth(ShapeParameter::getInstance()->getBorderWidth())
, m_borderStyle(ShapeParameter::getInstance()->getBorderStyle())
, m_borderColor(ShapeParameter::getInstance()->getBorderColor())
, m_shapeColor(ShapeParameter::getInstance()->getShapeColor())
, m_scaleFactor(ShapeParameter::getInstance()->getCanvasScale())
{
}

Shape::~Shape()
{
}

QPointF Shape::getStartPoint() const
{
	return m_startPoint;
}

QPointF Shape::getEndPoint() const
{
	return m_endPoint;
}

void Shape::setStartPoint(const QPointF& point)
{
	m_startPoint = point;
}

void Shape::setEndPoint(const QPointF& point)
{
	m_endPoint = point;
}

bool Shape::isShapeVaild() const
{
	return (m_startPoint.x() != m_endPoint.x() || m_startPoint.y() != m_endPoint.y());
}

ShapeType Shape::getShapeType()
{
	return ShapeType::None;
}

QRectF Shape::getShapeRect()
{
	return QRectF(m_startPoint, m_endPoint);
}

void Shape::drawOutline(QPaintDevice* parent)
{
	QPainter painter(parent);
	painter.setRenderHint(QPainter::Antialiasing);
	QTransform transform;
	transform.scale(m_scaleFactor, m_scaleFactor);
	painter.setTransform(transform);
	painter.setPen(QPen(Qt::black, 1.0, Qt::DashLine));
	painter.drawRect(getShapeRect());
}

void Shape::drawSelectedHighlight(QPaintDevice* parent, bool drawControl)
{
	QPainter painter(parent);
	painter.setRenderHint(QPainter::Antialiasing);
	QTransform transform;
	transform.scale(m_scaleFactor, m_scaleFactor);
	painter.setTransform(transform);
	painter.setPen(QPen(QColor(128, 0, 128), 2.0, Qt::SolidLine));
	int shapeWidth = m_endPoint.x() - m_startPoint.x();
	int shapeHeight = m_endPoint.y() - m_startPoint.y();
	if (shapeWidth <= 0 || shapeHeight <= 0)
	{
		return;
	}
	painter.drawRect(getShapeRect());
	if (!drawControl)
	{
		return;
	}
	QPointF shapeLeftTopXY = m_startPoint;
	qreal scale = ShapeParameter::getInstance()->getShapeScale();
	qreal halfLength = 4.0 * scale;
	for (int i = 0; i < 8; i++)
	{
		switch (i)
		{
		case 0:
			m_controlRect[i].setX(shapeLeftTopXY.x() - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() - halfLength);
			break;
		case 1:
			m_controlRect[i].setX(shapeLeftTopXY.x() + shapeWidth / 2.0 - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() - halfLength);
			break;
		case 2:
			m_controlRect[i].setX(shapeLeftTopXY.x() + shapeWidth - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() - halfLength);
			break;
		case 3:
			m_controlRect[i].setX(shapeLeftTopXY.x() + shapeWidth - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() + shapeHeight / 2.0 - halfLength);
			break;
		case 4:
			m_controlRect[i].setX(shapeLeftTopXY.x() + shapeWidth - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() + shapeHeight - halfLength);
			break;
		case 5:
			m_controlRect[i].setX(shapeLeftTopXY.x() + shapeWidth / 2.0 - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() + shapeHeight - halfLength);
			break;
		case 6:
			m_controlRect[i].setX(shapeLeftTopXY.x() - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() + shapeHeight - halfLength);
			break;
		case 7:
			m_controlRect[i].setX(shapeLeftTopXY.x() - halfLength);
			m_controlRect[i].setY(shapeLeftTopXY.y() + shapeHeight / 2.0 - halfLength);
			break;
		default:
			break;
		}
		m_controlRect[i].setWidth(2.0 * halfLength);
		m_controlRect[i].setHeight(2.0 * halfLength);
		painter.drawRect(m_controlRect[i]);
		painter.fillRect(m_controlRect[i], QColor(128, 0, 128));
	}
}

void Shape::move(const QPointF& offset)
{
	m_startPoint += offset;
	m_endPoint += offset;
}

void Shape::moveTop(QPointF pos)
{
	if (pos.y() - m_endPoint.y() <= -25)
	{
		m_startPoint.setY(pos.y());
	}
}

void Shape::moveBottom(QPointF pos)
{
	if (pos.y() - m_startPoint.y() >= 25)
	{
		m_endPoint.setY(pos.y());
	}
}

void Shape::moveLeft(QPointF pos)
{
	if (pos.x() - m_endPoint.x() <= -25)
	{
		m_startPoint.setX(pos.x());
	}
}

void Shape::moveRight(QPointF pos)
{
	if (pos.x() - m_startPoint.x() >= 25)
	{
		m_endPoint.setX(pos.x());
	}
}

void Shape::moveTopLeft(QPointF pos)
{
	if (pos.y() - m_endPoint.y() <= -25 && pos.x() - m_endPoint.x() <= -25)
	{
		m_startPoint = pos;
	}
	else if (pos.y() - m_endPoint.y() > -25 && pos.x() - m_endPoint.x() <= -25)
	{
		m_startPoint.setX(pos.x());
	}
	else if (pos.y() - m_endPoint.y() <= -25 && pos.x() - m_endPoint.x() > -25)
	{
		m_startPoint.setY(pos.y());
	}
}

void Shape::moveTopRight(QPointF pos)
{
	if (pos.y() - m_endPoint.y() <= -25 && pos.x() - m_startPoint.x() >= 25)
	{
		m_startPoint.setY(pos.y());
		m_endPoint.setX(pos.x());
	}
	else if (pos.y() - m_endPoint.y() > -25 && pos.x() - m_startPoint.x() >= 25)
	{
		m_endPoint.setX(pos.x());
	}
	else if (pos.y() - m_endPoint.y() <= -25 && pos.x() - m_startPoint.x() < 25)
	{
		m_startPoint.setY(pos.y());
	}
}

void Shape::moveBottomLeft(QPointF pos)
{
	if (pos.y() - m_startPoint.y() >= 25 && pos.x() - m_endPoint.x() <= -25)
	{
		m_startPoint.setX(pos.x());
		m_endPoint.setY(pos.y());
	}
	else if (pos.x() - m_endPoint.x() > -25 && pos.y() - m_startPoint.y() >= 25)
	{
		m_endPoint.setY(pos.y());
	}
	else if (pos.x() - m_endPoint.x() <= -25 && pos.y() - m_startPoint.y() < 25)
	{
		m_startPoint.setX(pos.x());
	}
}

void Shape::moveBottomRight(QPointF pos)
{
	if (pos.y() - m_startPoint.y() >= 25 && pos.x() - m_startPoint.x() >= 25)
	{
		m_endPoint = pos;
	}
	else if (pos.y() - m_startPoint.y() < 25 && pos.x() - m_startPoint.x() >= 25)
	{
		m_endPoint.setX(pos.x());
	}
	else if (pos.y() - m_startPoint.y() >= 25 && pos.x() - m_startPoint.x() < 25)
	{
		m_endPoint.setY(pos.y());
	}
}

void Shape::setShapeScale(qreal scale)
{
	m_scaleFactor = scale;
}

qreal Shape::getShapeScale()
{
	return m_scaleFactor;
}

void Shape::setBorderWidth(int width)
{
	m_borderWidth = width;
}

void Shape::setBorderStyle(Qt::PenStyle style)
{
	m_borderStyle = style;
}

void Shape::setBorderColor(QRgb color)
{
	m_borderColor = color;
}

void Shape::setShapeColor(QRgb color)
{
	m_shapeColor = color;
}

QRgb Shape::getBorderColor()
{
	return m_borderColor;
}

Qt::PenStyle Shape::getBorderStyle()
{
	return m_borderStyle;
}

QRgb Shape::getShapeColor()
{
	return m_shapeColor;
}

int Shape::getBorderWidth()
{
	return m_borderWidth;
}

const int Shape::getControlRectIndex(QPoint pos)
{
	for (int i = 0; i < 8; i++)
	{
		if (m_controlRect[i].contains(pos))
		{
			return i;
		}
	}
	return -1;
}